//
//  LQBaseAPIManager.m
//  LQBaseKit
//
//  Created by 戴志朋 on 15/10/26.
//  Copyright © 2015年 hzdracom. All rights reserved.
//

#import "LQBaseAPIManager.h"
#import <objc/runtime.h>
#import <UtilsMacro.h>
#import <ReactiveCocoa.h>
#import "LQBaseCache.h"
#import <JSONKit.h>

@implementation LQBaseAPIManager

+ (instancetype)sharedManager
{
    static dispatch_once_t onceToken;
    static LQBaseAPIManager *instance;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc]initWithBaseURL:nil];
    });
    return instance;
}

- (NSString *)jsonStringWithDictionary:(NSDictionary *)dic
{
    NSError * err;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic
                                                       options:0
                                                         error:&err];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData
                                                 encoding:NSUTF8StringEncoding];
    return jsonString;
}

- (id)jsonStringToJson:(NSString *)jsonString
{
    NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    return json;
}

- (NSDictionary *)objectFromData:(id)data{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList([data class], &propsCount);
    for(int i = 0;i < propsCount; i++){
        objc_property_t prop = props[i];
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
        id value = [data valueForKey:propName];
        
        if(value == nil){
            value = [NSNull null];
        }else{
            value = [self getObjectInternal:value];
        }
        
        [dic setObject:value forKey:propName];
    }
    return dic;
}

-(id)getObjectInternal:(id)obj{
    if([obj isKindOfClass:[NSString class]] ||
       [obj isKindOfClass:[NSNumber class]] ||
       [obj isKindOfClass:[NSNull class]]){
        return obj;
    }
    
    if([obj isKindOfClass:[NSArray class]]){
        NSArray *objarr = obj;
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
        
        for(int i = 0;i < objarr.count; i++){
            [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i];
        }
        
        return arr;
    }
    
    if([obj isKindOfClass:[NSDictionary class]]){
        NSDictionary *objdic = obj;
        
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
        
        for(NSString *key in objdic.allKeys){
            [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key];
        }
        return dic;
    }
    
    return [self objectFromData:obj];
}

- (NSString *)cacheKeyWithParameters:(NSDictionary *)parameters apiName:(NSString *)apiName
{
    return F(@"%@%@",apiName,parameters ? parameters : @"");
}

- (NSString *)cacheKeyWithApiName:(NSString *)apiName{
    return F(@"%@",apiName);
}

- (RACSignal *)requestWithMethod:(NSString *)method
                         apiName:(NSString *)apiName
                      parameters:(NSDictionary *)parameters
                     resultClass:(Class)resultClass{
    //缓存模式直接返回
    id cacheData = self.cachePloy != APICachePloy_Server ? [[LQBaseCache sharedCache]objectForKey:[self cacheKeyWithParameters:parameters apiName:apiName]] : nil;
    switch (self.cachePloy) {
        case APICachePloy_Cache:
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                [subscriber sendNext:cacheData];
                [subscriber sendCompleted];
                return nil;
            }];
            break;
        case APICachePloy_Normal:
            if (cacheData) {
                return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                    [subscriber sendNext:cacheData];
                    [subscriber sendCompleted];
                    return nil;
                }];
            }
            break;
        default:
            break;
    }
    return [RACSignal empty];
}

@end
